{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Controlling the AAS WorldWide Telescope Windows client using pywwt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook demonstrates how to use the AAS WorldWide Telescope Windows client using pywwt. You can find out more about this in the [documentation](http://pywwt.readthedocs.io/en/latest/windows.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First, we'll import the `WWTWindowsClient` class, as well as [numpy](http://www.numpy.org) and [h5py](http://www.h5py.org), which we'll need for this example. We will also import [astropy.units](https://docs.astropy.org/en/stable/units/index.html) to handle unit conversions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import h5py\n",
    "from astropy import units as u\n",
    "from pywwt.windows import WWTWindowsClient"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next, we'll connect to WorldWide Telescope:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "wwt = WWTWindowsClient()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now, we'll create a layer which we'll put data in later. Since this is tracer particle data from a radio minihalo simulation of a galaxy cluster core, we'll put the layer in the `\"Sky\"` frame and name it `\"minihalo\"`. We also need to specify the fields that will go into the layer, which in this case are just the spherical coordinates of the points and the color of the point. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "layer = wwt.new_layer(\"Sky\",\"minihalo\",[\"RA\",\"DEC\",\"ALT\",\"color\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We need to set the properties of this layer as well. We will construct a `props_dict` to hold the layer properties we want. A summary:\n",
    "\n",
    "- The coordinates are spherical.\n",
    "- The size of the point is relative to the screen.\n",
    "- The points have all the same scale.\n",
    "- The scale of the points is 16. \n",
    "- The points are lit on all sides. \n",
    "- This is not a time series dataset. \n",
    "- The \"altitude\" coordinate (or radius) is in megaparsecs.\n",
    "- The units of the RA coordinate are in degrees. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "props_dict = {\"CoordinatesType\":\"Spherical\",\n",
    "              \"MarkerScale\":\"Screen\",\n",
    "              \"PointScaleType\":\"Constant\",\n",
    "              \"ScaleFactor\":\"16\",\n",
    "              \"ShowFarSide\":\"True\",\n",
    "              \"TimeSeries\":\"False\",\n",
    "              \"AltUnit\":\"MegaParsecs\",\n",
    "              \"RaUnits\":\"Degrees\"}\n",
    "layer.set_properties(props_dict)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Though it probably already is, this call activates the layer in the view: "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "layer.activate()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we have to do some work to get the data out of the HDF5 file it's contained in. The data consists of a set of points, with cartesian coordinates in centimeters, and radio emissivity in cgs units. We'll map the radio emissivity to a color map from Matplotlib, and convert the coordinates to spherical. We'll put all of this in a dict, `data`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pywwt.windows import map_array_to_colors, convert_xyz_to_spherical\n",
    "fn = \"radio_halo_1kpc_hdf5_part_0200_reduced.h5\"\n",
    "f = h5py.File(fn, \"r\")\n",
    "cm_per_mpc = u.Mpc.to(u.cm)\n",
    "x = f[\"x\"][:] / cm_per_mpc # The coordinates in the file are in cm, this converts them to Mpc\n",
    "y = f[\"y\"][:] / cm_per_mpc\n",
    "z = f[\"z\"][:] / cm_per_mpc\n",
    "c = f[\"radio\"][:]\n",
    "color = map_array_to_colors(c, \"spectral\", scale=\"log\", vmin=1.0e-40, vmax=4.0e-23)\n",
    "data = convert_xyz_to_spherical(x, y, z)\n",
    "data[\"color\"] = color\n",
    "f.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we add this data in. We set `purge_all=True` to eliminate the data already in the layer (though it was empty so it's superfluous), and we set the `fly_to` parameter to fly to a particular location and zoom setting relative to the `\"Sky\"` frame:\n",
    "\n",
    "- Latitude: 48 degrees\n",
    "- Longitude: -12 degress\n",
    "- Zoom: $6 \\times 10^{11}$\n",
    "- Rotation: 0 radians\n",
    "- Angle: 0 radians"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "layer.update(data=data, purge_all=True, fly_to=[48.,-12.,6.0e11,0.,0.])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Just as a check, we can get the state of the current view (after the fly-to stops) and see that it matches up with the coordinates of our `fly_to` parameter:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "wwt.get_state()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}